package main

import (
	"bufio"
	"chatRoom/common"
	"database/sql"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"strings"
)

const (
	ONE   = "1"
	TOW   = "2"
	Three = "3"
)

var NumOnline int //在线人数

func main() {
	DB, err := common.InitDB() //连接数据库
	if err != nil {
		panic(err)
	} else {
		fmt.Println("数据库连接成功！")
	}
	fmt.Println("退出:	\\q")
	fmt.Println("修改姓名：	\\rN")
	fmt.Println("修改密码：	\\rP")
	fmt.Println("发送文件：	\\file")
	fmt.Println("切换聊天模式：输入@ XXX 或者 @ @all 对应公聊和私聊模式：")
	fmt.Println("普通消息：直接输入")
	fmt.Println("姓名密码要求：\n" +
		"\t\t不允许 包含\"/\\,+=-><^%@^()|\"\n" +
		"\t\t不允许 长度超过20(字节)\n" +
		"\t\t 密码 长度不小于8（字节）")
	reader := bufio.NewReader(os.Stdin)
	exit := false
	for true {
		fmt.Println("1.登录账号")
		fmt.Println("2.注册账号")
		fmt.Println("3.离开")
		line, _, err := reader.ReadLine()
		if err != nil {
			fmt.Println("输入错误！")
			return
		}
		switch string(line) {
		case ONE:
			if u, i := LogIn(DB); i {
				connect(u, DB)
				common.UpdateOnline(DB, u, 1)
				exit = true
			}
		case TOW:
			if _, i := common.Register(DB); i {
				break
			}
		case Three:
			exit = true
		default:
			fmt.Println("输入错误请重新输入：")
		}
		if exit {
			break
		}
	}
}

func LogIn(DB *sql.DB) (*common.User, bool) {
	fmt.Println("请输入用户名（\\q退出）：")
	reader := bufio.NewReader(os.Stdin)
	name, password := "", ""
	for {
		buf := make([]byte, 1024)
		n, err := reader.Read(buf)
		name = strings.Trim(string(buf[:n]), "\r\n")
		if err != nil {
			log.Println(err)
			return nil, false
		}
		if name == "\\q" {
			return nil, false
		}
		if u, i := common.QueryName(DB, name); i {
			fmt.Println("密码：")
			password, err = reader.ReadString('\n')
			if err != nil {
				log.Println(err)
				return nil, false
			}
			password = strings.Trim(password, "\r\n")
			if u.Pwd == password && u.IsOnline == 1 {
				common.UpdateOnline(DB, u, 0)
				return u, true
			} else {
				fmt.Println("用户名或密码错误,或者该用户已在线。请重新输入（\\q退出）：")
				continue
			}
		} else {
			fmt.Println("用户名或密码错误,或者该用户已在线。请重新输入（\\q退出）：")
		}
	}
	return nil, false
}

func connect(u *common.User, DB *sql.DB) {
	conn, err := net.Dial("tcp", "127.0.0.1:20000")
	if err != nil {
		log.Println(err)
		return
	}
	go write(conn, u, DB) //发送消息到server端
	var buf [1024]byte
	for true {
		n, err := conn.Read(buf[:])
		if err == io.EOF {
			return
		} else if err != nil {
			log.Println(err)
			return
		}
		fmt.Println(string(buf[:n]))
	}
	_ = conn.Close() //关闭连接
}

func write(conn net.Conn, u *common.User, DB *sql.DB) {
	reader := bufio.NewReader(os.Stdin)
	conn.Write([]byte(u.Name))
	buf := make([]byte, 1024)
	for true {
		line, _, err := reader.ReadLine()
		if err != nil {
			log.Println(err)
			return
		}
		msg := string(line)
		if msg == "\\rN" || msg == "\\rP" {
			fmt.Println("请输入新的名字或新密码：")
			for true {
				n, err := reader.Read(buf[:])
				if err != nil {
					log.Println(err)
					return
				}
				new := strings.Trim(string(buf[:n]), "\r\n")
				if new == "\\q" {
					break
				}
				if common.CheckNameAndPassword(n, new) {
					common.UpdateUser(DB, u, new, msg)
					break
				} else {
					fmt.Println("新名字或密码的格式错误，请重新输入（\\q退出）：")
				}
			}
			continue
		}
		if msg == "@" || msg == "\\file" {
			_, err = conn.Write(line)
			line, _, err = reader.ReadLine()
			_, err = conn.Write(line)
		} else if msg == "\\q" {
			_, err = conn.Write([]byte(msg))
		} else {
			msg = u.Name + ": " + msg
			_, err = conn.Write([]byte(msg))
		}
		if err != nil {
			log.Println(err)
			return
		}
	}
}
